﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Windows.Forms;
using System.Threading;
using System.Net.Sockets;
using System.Drawing;

namespace MulticastTV
{
    /// <summary>
    /// Check if vlc server is alive (unicast mode)
    /// </summary>
    class UnicastConntest
    {
        HttpWebRequest req;
        Thread tr;
        Thread tr2;
        Label label;
        IPAddress valid;
        VariablesToThread tv;
        
        /// <summary>
        /// is Alive
        /// </summary>
        /// <param name="strIp">Server Ip</param>
        /// <param name="intPort">Server Port</param>
        /// <param name="labLabel16">Settings form status label</param>
        /// <param name="vlc">Force vlc server check</param>
        public void check(string strIp, int intPort, Label labLabel16, bool vlc) 
        {
            if (!IPAddress.TryParse(strIp, out valid))
            { 
                return;
            }
            string page = "";
            if (labLabel16 != null)
                label = labLabel16;
            else
                label = null;
            // vlc server
            if (Properties.Settings.Default.UnicastServer == "vlc" || vlc)
            {
                page = "http://" + strIp + ":" + intPort.ToString() + "/requests/status.xml";

                req = (HttpWebRequest)WebRequest.Create(page);
                req.Method = "GET";
                req.KeepAlive = true;
                req.Timeout = 1500;
                tr = new Thread(new ThreadStart(response));
                tr.IsBackground = true;
                tr.Start();
            }
            // udprelay server (respondes without headers so we can't use httpwebrequst class)
            else
            {
                tv = new VariablesToThread();
                tv.intPort = intPort;
                tv.strIp = strIp;
                tr2 = new Thread(new ThreadStart(udpRelayConnect));
                tr2.IsBackground = true;
                tr2.Start();                
            }
        }

        private void response ()
        {
            try
            {
                HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
                string tx="Server is responding.";
                if (label!=null)
                    label.Invoke(new updateCallback(updatFromThread), tx, Color.Green);
                resp.Close();

            }
            catch
            {
                string tx="Server not responding.";
                if (label!=null)
                    label.Invoke(new updateCallback(updatFromThread), tx, Color.Red);

            }
        }

        private void udpRelayConnect()
        {
            Socket socket;
            try
            {
                IPAddress ip = IPAddress.Parse(tv.strIp);
                socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IPEndPoint ipEnd = new IPEndPoint(ip, tv.intPort);
                socket.ReceiveTimeout = 5000;
                socket.Connect(ipEnd);
            }
            catch { connectionError(); return; }

            try 
            {
                // Send
                Byte[] bytesSent = Encoding.ASCII.GetBytes("http://" + tv.strIp + ":" + tv.intPort + "/control/info");
                socket.Send(bytesSent);

                // Receive the server home page content.
                Byte[] bytesReceived = new Byte[256];
                int bytes = 0;
                string page = "";

                do
                {
                    bytes = socket.Receive(bytesReceived, bytesReceived.Length, 0);
                    page = page + Encoding.ASCII.GetString(bytesReceived, 0, bytes);
                }
                while (bytes > 0);
                if (socket != null)
                    socket.Close();
                udpRelayAlive();
            }
            catch 
            {  
                connectionError();
                socket.Close();
                return; 
            }
        }

        private void connectionError()
        {
            string tx = "Server not responding.";
            if (label != null)
                label.Invoke(new updateCallback(updatFromThread), tx, Color.Red);

        }

        private void udpRelayAlive()
        {
            string tx = "Server is responding.";
            if (label != null)
                label.Invoke(new updateCallback(updatFromThread), tx, Color.Green);

        }

        public delegate void updateCallback(string text, Color col);
        
        private void updatFromThread(string text, Color col) {

            label.Text = text;
            label.ForeColor = col;
        }

    }
    class VariablesToThread
    { 
        public string strIp;
        public int intPort;
    }
}
